// kernel/printf.c
#include "printf.h"
#include "console.h"
#include <stdarg.h>

// 数字转字符串（支持十进制/十六进制）
static void print_num(int num, int base, int sign) {
    char buf[16];
    int i = 0;
    int is_neg = 0;


    
    if (sign && num < 0) {
        is_neg = 1;
        num = -num;
    }

    do {
        int digit = num % base;
        buf[i++] = (digit < 10) ? '0' + digit : 'a' + (digit - 10);
        num /= base;
    } while (num > 0);

    if (is_neg) console_putc('-');
    while (--i >= 0) console_putc(buf[i]);
}

// 核心格式化输出
int printf(const char *fmt, ...) {
    va_list ap;
    va_start(ap, fmt);

    for (int i = 0; fmt[i]; i++) {
        if (fmt[i] != '%') {
            console_putc(fmt[i]);
            continue;
        }
        i++; // 跳过 '%'
        switch (fmt[i]) {
            case 'd': print_num(va_arg(ap, int), 10, 1); break;// 十进制有符号整数
            case 'x': print_num(va_arg(ap, int), 16, 0); break;// 十六进制无符号整数
            case 's': console_puts(va_arg(ap, char*)); break;// 字符串
            case 'c': console_putc(va_arg(ap, int)); break;// 字符
            case 'p':
    printptr(va_arg(ap, uint64));
    break;
            case '%': console_putc('%'); break;
            default:  console_putc('?'); break; // 未知格式符
        }
    }
    va_end(ap);
    return 0;
}
void printptr(uint64 x) {
    char buf[16];
    for(int i = 0; i < 16; i++, x <<= 4)
        buf[i] = "0123456789abcdef"[(x >> 60) & 0xf];
    
    uart_puts("0x");
    for(int i = 0; i < 16; i++)
        uart_putc(buf[i]);
}
